

#import <appkit/appkit.h>

#import "Global.h"

#define CHUNK 127

const char *localString(const char *aString)
{
   	return NXLocalizedString(aString,NULL,aString);
}

const char *appDirectory()
{
	static char appDirectory[MAXPATHLEN] = { '\0' };
	char temp[MAXPATHLEN+1];
	char *ptr = NULL;

	if(!appDirectory[0]) {
		strcpy(appDirectory, NXArgv[0]);
		if(ptr = rindex(appDirectory, '/')) *ptr = '\0';

		if (appDirectory && appDirectory[0]) {
			getwd(temp);
			chdir(appDirectory);
			getwd(appDirectory);
			chdir(temp);
		}
#ifdef DEBUG
		printf("appDirectory = %s\n",appDirectory);
#endif
	}
	return appDirectory;
}

BOOL isThereSwapSpace(int imageSize)
{
    int rtn;
    struct statfs stfs;

    rtn = statfs("/private/vm", &stfs);
    if (rtn || ((stfs.f_bavail * stfs.f_bsize) < 0)) {
#ifdef DEBUG
		printf("NXApp: No space available on Hard Disk\n");
#endif
		NXRunAlertPanel(localString("Disk is Full"),
						localString("Enough swapspace is not available.  Please make more space by erasing old files or by rebooting the computer."),
						localString("Cancel"),NULL,NULL);
		return NO;
    } else if (rtn || ((stfs.f_bavail * stfs.f_bsize) < imageSize)) {
#ifdef DEBUG
		printf("NXApp: Not enough space available on Hard Disk\n");
		printf("            Required size = %d Kbytes\n",imageSize/1024);
#endif
		rtn = NXRunAlertPanel(localString("Disk is Full"),
							localString("The swapfile is full.  Please make more space by erasing old files or by rebooting the computer.  Continuing may cause a crash."),
							localString("Cancel"),
							localString("Continue"),NULL);
		if (rtn == NX_ALERTDEFAULT) return NO;
		else			    return YES;
    }
    return YES;
}

char *stripnl(char *s)
{
    char *p;
    for (p=s;*p;p++) if (*p == '\n' || *p == '\r') *p = '\0';
    return s;
}

char *execstr(char *s)
/* Executes the passed string and returns a string value in that pointer */
/* Stolen from Opener 3.0 */
{
    FILE *f = popen(s,"r");
    char *p = s;
    *s = '\0';
    if (f){
        while (fgets(p,256,f))
            stripnl(p), p += strlen(p);
        pclose(f);
    }
    return s;
}

void fillMemory(unsigned char *ptr, int numBytes)
{
	int i;
	for (i=0;i < numBytes; i++) {
		*(ptr+i) = 0xff;
	}
}

/* Functions for creating and managing a dynamically-allocated fileList */
/* - really just a list of strings.  They seem to be somewhat useful.   */

char **addFile(const char *file, char **list, int count, NXZone *zone)
/* Adds the specified filename to the list of filenames.  It allocates 
 * more memory in chunks as needed.
 */
{	
    if (!list) list = (char **)NXZoneMalloc(zone,CHUNK*sizeof(char *));
    list[count] = (char *)NXZoneMalloc(zone,(strlen(file)+1)*sizeof(char));
    strcpy(list[count], file);
    count++;
    if (!(count% CHUNK)) {
		list = (char **)NXZoneRealloc(zone,list,(((count/CHUNK)+1)*CHUNK)*sizeof(char *));
    }
    list[count] = NULL;
    return list;
}

void freeList(char **list)
/* Frees the array of filenames */
 {
    char **strings;

    if (list) {
		strings = list;
		while (*strings) NX_FREE(*strings++);
		NX_FREE(list);
    }
}


NXRect *calcFrame(id printInfo, NXRect *viewRect)
/*
 * Calculates the size of the page the user has chosen minus its margins.
 */
{
    float lm, rm, bm, tm;
    const NXRect *paperRect;
	float scale;

    viewRect->origin.x = viewRect->origin.y = 0.0;
    paperRect = [printInfo paperRect];
	scale = 1 / [printInfo scalingFactor];
    [printInfo getMarginLeft:&lm right:&rm top:&tm bottom:&bm];
    viewRect->size = paperRect->size;
    viewRect->size.width -= lm + rm;
    viewRect->size.height -= tm + bm;
    viewRect->size.width *= scale;
	viewRect->size.height *= scale;
    return viewRect;
}

void strtoRect(char * inputString, NXRect * frame)
{
    char	*start, *next;
    
    frame->origin.y = frame->origin.y = 0.0;
    frame->size.width = frame->size.height = 0.0;
    
    start = inputString;
    if ( *start == ' ' ) start++;
    if ( *start == 'x' ) start++;
    if ( *start == '\0' ) return;
    frame->origin.x = strtod(start, &next);
    if ( start == next ) return;

    start = next;
    if ( *start == ' ' ) start++;
    if ( *start == 'y' ) start++;
    if ( *start == '\0' ) return;
    frame->origin.y = strtod(start, &next);
    if ( start == next ) return;
    
    start = next;
    if ( *start == ' ' ) start++;
    if ( *start == 'w' ) start++;
    if ( *start == '\0' ) return;
    frame->size.width = strtod(start, &next);
    if ( start == next ) return;
    
    start = next;
    if ( *start == ' ' ) start++;
    if ( *start == 'h' ) start++;
    if ( *start == '\0' ) return;
    frame->size.height = strtod(start, &next);
    if ( start == next ) return;
    
    return;    
}

BOOL includesType(const NXAtom *types, NXAtom type)
{
	if (types)
		while (*types)
			if (*types++ == type)
				return YES;
    return NO;
}

